問題解説: ホビットの国 第一のトラブル

問題文

一行はギルドの依頼で、サーバーを構築しているホビットカンパニーを訪れた。

エイト「さすがにカンパニーっていうだけあって、ホビットの国でも建物は大きいわね。とりあえず入りましょ。社長が待っているわ」

最上階の社長室に入ると、少しふくよかな体型をしたホビットが待ち構えていた。

ホビット社長「やーよく来てくれた。 現在とあるトラブルがカンパニー内で起きている。それを解決して欲しいんだ」

エイト「あんたたちにかかれば簡単な話よね?」

ホビット社長「実は、サーバーが一台重くて全く動かないんだ。原因もわかっていなくてな。お願い出来るかな?」

達成すべき事項

benchサーバにあるbenchmarkerコマンドが正常終了する。

問題内容

benchサーバとserverサーバが存在しており、serverにはApacheとheavenと呼ばれるアプリケーションが動いていました。

このheavenというのは、golang製のHTTPサーバです。やってきたHTTPリクエストに対して、10秒待機した後にリクエストを返答するお行儀の悪いアプリケーションです。WordPressやGitLabなどのバックエンドアプリケーションで処理に時間がかかっている現象を模倣しています。

「達成すべき事項」で触れられている benchmarker コマンドというのは、golang製のHTTPベンチマーカでした。server上にて動作しているApacheに対して、高速にHTTPリクエストを送信します。

benchmarkerコマンドで発行された多くのHTTPリクエストに対して、Apacheが非常に多くのコネクションを持ってしまい、捌ききれなくなってしまう現象が発生していまう、というのが今回発生していたトラブルでした。

回答例

サーバのリソースには余裕があるため、Apacheのチューニングを行い、捌くことができるコネクションの数を増やします。
具体的には、以下の値を apache2.conf など読み込まれる部分に入力します。

ServerLimit         100
StartServers         100
MaxRequestWorkers         3000
MinSpareThreads     25
MaxSpareThreads     75
ThreadsPerChild     25
MaxRequestsPerChild  3000

この値は一例であり、実際にbenchmarkerコマンドを用いて解決出来ていれば問題無い、という判断でした。

講評

今回のトラブルが発生している際に、Apacheのエラーログには下記のような出力がありました。

[mpm_prefork:error] [pid 14998] AH00161: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting

エラーログに対処方法がそのまま出力されており、比較的容易に解ける問題として出題しました。

結果としては8割ほどのチームが基準点を超える解答を提出しており、比較的狙い通りになったのではないかと考えています。

おわりに

Apacheなどのミドルウェアのトラブルシューティングには出力されるログが非常に重要です。
毎回ログを読む問題が出題されていますが、それぐらい重要な事項となりますので、是非ログを読む力を鍛えてもらえればと思います。

また、使用したソースコードは以下で公開されています。

https://github.com/whywaita/sleep-princess

もしbenchmarkerコマンドの実行に失敗した場合にはsugyan/termburnによって炎が出たかと思いますが、正しく動いていたなら幸いです。